package net.sk.ws;

import java.io.IOException;
import java.util.HashMap;

import javax.servlet.http.HttpSession;

import net.bat.util.Cfg;
import net.bat.util.Encrypt;
import net.sk.pt.BindFilter;
import net.sk.pt.IConsumer;
import net.sk.pt.IFilter;
import net.sk.pt.IProvider;
import net.sk.pt.State;
import net.sk.web.Provider;
import net.sk.web.StateCenter;

import org.eclipse.jetty.websocket.WebSocket.OnTextMessage;
import org.jabsorb.JSONSerializer;
import org.jabsorb.serializer.MarshallException;
import org.jabsorb.serializer.UnmarshallException;

public class WSket implements OnTextMessage,IConsumer {
	private Connection conn;  
	private Object key;
	private JSONSerializer ser;
	private Provider pr;
	private HttpSession session;
	public static String CN_WHO_AM_I = "CN_WHO_AM_I";
	private String sessionId;
	public static String PRE_WS = "WS_";

	WSket(HttpSession session){
		this.session = session;
		this.sessionId=session.getId();
	}
	private String toJSON(State s){
		try {
			return ser.toJSON(s);
		} catch (MarshallException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		return null;
	}
	private Object fromJSON(String str){
		try {
			return ser.fromJSON(str);
		} catch (UnmarshallException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		return null;
	}
	@Override
	public void onClose(int arg0, String arg1) {
		// TODO Auto-generated method stub
		this.destory();
	}

	@Override
	public void onOpen(Connection arg0) {
		// TODO Auto-generated method stub
		this.conn = arg0;
		this.init(PRE_WS+this.hashCode());
		sendme();
	}

	@Override
	public void onMessage(String arg0) {
		State fo=null;
		// TODO Auto-generated method stub
		try {
			 fo = (State)ser.fromJSON(arg0);
		} catch (UnmarshallException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		if(fo.getCn().equals("SC_SUBSCRIBE")){
			subscribe(fo);
		}
	}
	//订阅系统消息
	public void subscribe(State fo){
		String[] prs = (String[])fo.getItems().get("prs");
		String[][] fids = (String[][])fo.getItems().get("fids");
		String[] cns = (String[])fo.getItems().get("cns");
		IFilter[] fls = null;
		if(fids!=null){
			fls = new IFilter[fids.length];
			for(int i=0; i<fids.length; i++){
				if(cns[i]==null || cns[i].trim().equals("")){
					fls[i]=null;
				}else{
					fls[i] = new BindFilter(cns[i],fids[i]);
				}
			}
		}
		switch(fo.getAction()){
		case State.ACTION_ADD:
			Cfg.getSC().subscribeProvider(this, prs, fls);
			break;
		case State.ACTION_REMOVE:
			Cfg.getSC().unSubscribeProvider(this, prs);
			break;
		}
	}

	@Override
	public Object getKey() {
		// TODO Auto-generated method stub
		return key;
	}

	public void sendme(){
		State s = new State();
		s.setAction(State.ACTION_PUT);
		s.setCn(CN_WHO_AM_I);
		s.setKey(this.key);
		send(null,s);
	}
	@Override
	public boolean send(IProvider pr, State s) {
		// TODO Auto-generated method stub
		try {
			if(pr!=null){
				s.setPr(pr.getKey());
			}
			conn.sendMessage(toJSON(s));
			return true;
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
			this.destory();
			return false;
		}
	}

	@Override
	public void clearStateByPr(IProvider pr) {
		// TODO Auto-generated method stub
		
	}

	@Override
	public void init(Object key) {
		// TODO Auto-generated method stub
		this.key = key;
		StateCenter sc = Cfg.getSC();
		//sc.addConsumer(this);
		Cfg.getSC().ws_open(this.sessionId, this);
		pr = null;
		ser = new JSONSerializer();
		try {
			ser.registerDefaultSerializers();
		} catch (Exception e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}
	public Provider getPr() {
		return pr;
	}
	public void setPr(Provider pr) {
		this.pr = pr;
	}
	@Override
	public void destory() {
		// TODO Auto-generated method stub
		Cfg.getSC().ws_close(this.sessionId, this);
		//Cfg.getSC().removeConsumer(this);
		if(pr!=null)
			pr.destory();
	}

}
